package com.ygq.controller;


import DO.LogoDO;
import DO.StudentDO;
import DTO.AddLogoDTO;
import VO.WorkScoreVO;
import com.ygq.LogoService;
import com.ygq.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import result.Result;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/teacher")
@Slf4j
public class logoController {

    @Autowired
    private LogoService logoService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 发布签到
     * @param addLogoDTO
     * @return
     */
    @PostMapping("/sublogo")
    @Transactional
    public Result<String> logo(@RequestBody AddLogoDTO addLogoDTO){
        if (addLogoDTO.getLogo() == null ||
                addLogoDTO.getClasses() == null ||
                addLogoDTO.getTime() == null){
            return Result.error("error",201);
        }
        if (addLogoDTO.getTime().isBefore(LocalDateTime.now().plusMinutes(3))){
            // 表示签到时间不足三分钟
            return Result.error("",701);
        }
        if (addLogoDTO.getTime().isAfter(LocalDateTime.now().plusMinutes(30))){
            // 表示签到时间超过30分钟
            return Result.error("",701);
        }




        // 1.先判断签到名称是否重复 3个小时以内
        if (logoService.getByIsrepeat(addLogoDTO)==-1){
            return Result.error("error",202);
        }
        if (logoService.getByIsrepeat(addLogoDTO)>0){
            // 表示在3个小时以内该班级重复提交签到
            return Result.error("error",203);
        }

        String key_pro = UUID.randomUUID().toString(); // 生成redis key的前缀
        LocalDateTime nowTime = LocalDateTime.now();   // 获取当前时间
        // 2.根据classId查询出对应的班级学生的id信息
        for (Integer aClass : addLogoDTO.getClasses()) {
            List<Integer> userIds = studentService.getUserIdByClassId(aClass);
            for (Integer userId : userIds) {
                 // key 的命名方法：key_pro ： classId_： userId; uuid+班级id+学生id
                String key = key_pro + ":" + aClass + "_:" + userId;
                // 0 标识未签到，默认未签到，全部设置为0
                stringRedisTemplate.opsForValue().set(key,"0");

                // 设置这个保存的时间为3个小时，多15秒预留空间
                long expirationTimeInSeconds = 3*60*60 + 15;
                stringRedisTemplate.expire(key, expirationTimeInSeconds, TimeUnit.SECONDS);
            }
            // 3. 最后向签到表中添加数据,分班级
            LogoDO logoDO = new LogoDO();
            logoDO.setLogo(addLogoDTO.getLogo());
            logoDO.setUuid(key_pro);
            logoDO.setClassId(aClass);
            logoDO.setCreatedTime(nowTime);
            logoDO.setEndTime(addLogoDTO.getTime());
            logoService.save(logoDO);
        }
        return Result.success(null);
    }


    /**
     * 获取签到信息，三小时以内的数据
     * @return
     */
    @GetMapping("/getLogoList")
    public Result<List<LogoDO>> getLogoList(){
        return Result.success(logoService.getAll());
    }


    /**
     * 获取签到成绩，3个小时以内
     * @param id 签到表id
     * @return
     */
    @GetMapping(value = "/getLogoScore", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity<Resource> downloadExcel(@RequestParam Integer id) {
        LogoDO logoDO = logoService.getById(id);
        if (logoDO == null){
            return null;
        }

        List<StudentDO> studentDOList = studentService.getByIdToTwo(logoDO.getClassId());
        // 创建新的工作簿
        Workbook workbook = new XSSFWorkbook();
        // 创建工作表
        Sheet sheet = workbook.createSheet("WorkScores");

        // 创建标题行
        Row headerRow = sheet.createRow(0);
        headerRow.createCell(0).setCellValue("序号");
        headerRow.createCell(1).setCellValue("姓名");
        headerRow.createCell(2).setCellValue("学号");
        headerRow.createCell(3).setCellValue("是否签到");

        // 填充数据行
        for (int i = 0; i < studentDOList.size(); i++) {
            String key = logoDO.getUuid() + ":" + logoDO.getClassId() + "_:" + studentDOList.get(i).getId();
            String logo = stringRedisTemplate.opsForValue().get(key);
            Row dataRow = sheet.createRow(i + 1); // 从第二行开始
            dataRow.createCell(0).setCellValue(i+1);
            dataRow.createCell(1).setCellValue(studentDOList.get(i).getUsername());
            dataRow.createCell(2).setCellValue(studentDOList.get(i).getStudentNumber());
            dataRow.createCell(3).setCellValue(Objects.equals(logo, "1") ?"签到":"未签到");
        }

        // 写入到输出流中
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        try {
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
            // 处理异常，例如返回错误响应
        }

        // 创建ByteArrayResource对象
        Resource resource = new ByteArrayResource(outputStream.toByteArray());

        // 设置HTTP响应头
        String filename = logoDO.getLogo() + ".xlsx";
        return ResponseEntity.ok()
                .header("Content-Disposition", "attachment; filename=" + filename)
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(resource);
    }
}
